package com.framework.boc.statistics.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.framework.boc.statistics.entity.Template;
import com.framework.boc.statistics.entity.TemplateField;
import com.framework.boc.statistics.mapper.TemplateMapper;
import com.framework.boc.statistics.response.vo.TableStructureVo;
import com.framework.boc.statistics.response.vo.TemplateStructureVo;
import com.framework.boc.statistics.service.ITemplateService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 统计模板表 服务实现类
 * </p>
 *
 * @author Leil
 * @since 2020-12-23
 */
@Service
public class TemplateServiceImpl extends ServiceImpl<TemplateMapper, Template> implements ITemplateService {

    @Autowired
    TemplateFieldServiceImpl templateFieldService;

    /**
     * 新增或更新模板
     *
     * @param template 模板对象
     * @return 新增或更新结果
     */
    public boolean addOrUpdate(Template template) {
        if (template.getId() == 0) {
            template.setId(null);
            template.setCreateDate(new Date());
            template.setCreateUser("admin");
        }
        boolean bool = this.saveOrUpdate(template);
        return bool;
    }

    /**
     * 获取模板结构
     * @param templateId    模板ID
     * @return              模板结构对象
     */
    public TemplateStructureVo getTemplateStructure(Integer templateId) {
        Template template = this.getById(templateId);
        List<TemplateField> list = this.templateFieldService.list(Wrappers.<TemplateField>lambdaQuery()
                        .eq(TemplateField::getTemplateId, templateId)
                        .orderByAsc(TemplateField::getId));
        List<String> props = list.stream().map(TemplateField::getFieldName).collect(Collectors.toList());

        Map<String, TableStructureVo> tableStructure = this.getTableStructure(list);
        TemplateStructureVo templateStructureVo = new TemplateStructureVo();
        templateStructureVo.setProps(props);
        templateStructureVo.setName(template.getName());
        templateStructureVo.setDescription(template.getDescription());
        templateStructureVo.setRemark(template.getRemark());
        templateStructureVo.setTableStructure(tableStructure);
        return templateStructureVo;
    }

    /**
     * 获取表格结构
     * @param list          field集合
     * @return              表格结构（父级节点名称《==》父级节点及子节点层级对象）
     */
    private Map<String, TableStructureVo> getTableStructure(List<TemplateField> list) {


        Map<String, TableStructureVo> map = new HashMap<>();
        for (TemplateField templateField : list) {
            String chTitle = templateField.getChTitle();
            String[] labels = chTitle.split("/");
            String parentLabel = labels[0];
            TableStructureVo parent = map.get(parentLabel);
            if (parent == null) {
                parent = new TableStructureVo();
                parent.setLabel(parentLabel);
                if (labels.length == 1) {
                    parent.setProp(templateField.getFieldName());
                }
            }
            this.recurInsertTableStructure(parent, labels, templateField.getFieldName(), 1, labels.length);
            map.put(parentLabel, parent);
        }
        return map;
    }


    /**
     * 递归的插入父级节点的子节点
     * @param parent        顶级父节点
     * @param childLabels   子标签数组
     * @param childProp     子字段名称
     * @param index         当前节点标签索引
     * @param deep          递归最大深度
     */
    private void recurInsertTableStructure(TableStructureVo parent, String[] childLabels, String childProp, int index, int deep) {
        if (index >= deep) {
            return;
        }
        String childLabel = childLabels[index];
        Map<String, TableStructureVo> children = parent.getChildren();
        if (children == null) {
            parent.setChildren(new HashMap<>());
        }
        TableStructureVo child = parent.getChildren().get(childLabel);
        if (child != null) {
            this.recurInsertTableStructure(child, childLabels, childProp, ++index, deep);
            return;
        }
        child = new TableStructureVo();
        child.setLabel(childLabel);
        if (index == deep - 1) {
            child.setProp(childProp);
        }
        parent.getChildren().put(childLabel, child);
        this.recurInsertTableStructure(child, childLabels, childProp, ++index, deep);
    }

    /**
     * 删除模板
     * @param templateId    模板ID
     * @return              删除结果
     */
    public boolean deleteTemplate(Integer templateId) {
        // 先删除字段
        boolean bool1 = this.templateFieldService.remove(
                Wrappers.<TemplateField>lambdaQuery()
                        .eq(TemplateField::getTemplateId, templateId));
        boolean bool2 = this.removeById(templateId);
        return bool1 && bool2;
    }
}
